<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highscore - The Boost C++ Libraries - Filesystem</title>
<link rel="stylesheet" href="css/highscore.css" type="text/css">
<link rev="made" href="mailto:boris@highscore.de">
<link rel="home" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="up" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="prev" href="interprocesscommunication.html" title="Chapter 8: Interprocess Communication">
<link rel="next" href="datetime.html" title="Chapter 10: Date and Time">
<link rel="chapter" href="introduction.html" title="Chapter 1: Introduction">
<link rel="chapter" href="smartpointers.html" title="Chapter 2: Smart Pointers">
<link rel="chapter" href="functionobjects.html" title="Chapter 3: Function Objects">
<link rel="chapter" href="eventhandling.html" title="Chapter 4: Event Handling">
<link rel="chapter" href="stringhandling.html" title="Chapter 5: String Handling">
<link rel="chapter" href="multithreading.html" title="Chapter 6: Multithreading">
<link rel="chapter" href="asio.html" title="Chapter 7: Asynchronous Input and Output">
<link rel="chapter" href="interprocesscommunication.html" title="Chapter 8: Interprocess Communication">
<link rel="chapter" href="filesystem.html" title="Chapter 9: Filesystem">
<link rel="chapter" href="datetime.html" title="Chapter 10: Date and Time">
<link rel="chapter" href="serialization.html" title="Chapter 11: Serialization">
<link rel="chapter" href="parser.html" title="Chapter 12: Parser">
<link rel="chapter" href="containers.html" title="Chapter 13: Containers">
<link rel="chapter" href="datastructures.html" title="Chapter 14: Data Structures">
<link rel="chapter" href="errorhandling.html" title="Chapter 15: Error Handling">
<link rel="chapter" href="castoperators.html" title="Chapter 16: Cast Operators">
<link rel="section" href="filesystem.html#filesystem_general" title="9.1 General">
<link rel="section" href="filesystem.html#filesystem_paths" title="9.2 Paths">
<link rel="section" href="filesystem.html#filesystem_files_and_directories" title="9.3 Files and Directories">
<link rel="section" href="filesystem.html#filesystem_fstream" title="9.4 File Streams">
<link rel="section" href="filesystem.html#filesystem_exercises" title="9.5 Exercises">
<meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://www.highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1) gen true for "http://highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1))'>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link href="http://www.highscore.de/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script><script type="text/javascript" src="js/jquery.event.drag-1.5.min.js"></script><script type="text/javascript" src="js/highscore.js"></script>
</head>
<body>
<div lang="en" class="docbook chapter" title="Chapter 9: Filesystem">
<p class="title">The Boost C++ Libraries</p>
<script type="text/javascript">
          var titlepage = "Front page";
        
      var titles = new Array(titlepage,
      
        "Chapter 1: Introduction",
      
        "Chapter 2: Smart Pointers",
      
        "Chapter 3: Function Objects",
      
        "Chapter 4: Event Handling",
      
        "Chapter 5: String Handling",
      
        "Chapter 6: Multithreading",
      
        "Chapter 7: Asynchronous Input and Output",
      
        "Chapter 8: Interprocess Communication",
      
        "Chapter 9: Filesystem",
      
        "Chapter 10: Date and Time",
      
        "Chapter 11: Serialization",
      
        "Chapter 12: Parser",
      
        "Chapter 13: Containers",
      
        "Chapter 14: Data Structures",
      
        "Chapter 15: Error Handling",
      
        "Chapter 16: Cast Operators",
      
      "");

      
          var titlehtml = "frontpage.html";
        
      var filenames = new Array(titlehtml,
      
        "introduction.html",
      
        "smartpointers.html",
      
        "functionobjects.html",
      
        "eventhandling.html",
      
        "stringhandling.html",
      
        "multithreading.html",
      
        "asio.html",
      
        "interprocesscommunication.html",
      
        "filesystem.html",
      
        "datetime.html",
      
        "serialization.html",
      
        "parser.html",
      
        "containers.html",
      
        "datastructures.html",
      
        "errorhandling.html",
      
        "castoperators.html",
      
      "");

      
      document.open();
      document.write('<form action="" class="toc">');
      document.write('<select size="1" onchange="location.href=options[selectedIndex].value">');
      for (var i = 0; i < titles.length && i < filenames.length; ++i) {
        if (titles[i] != "" && filenames[i] != "") {
          document.write('<option');
          document.write(' value="' + filenames[i] + '"');
          var expr = new RegExp('[/\]' + filenames[i] + '$');
          if (expr.test(location.href)) {
            document.write(' selected="selected"');
          }
          document.write('>' + titles[i] + '<\/option>');
        }
      }
      document.write('<\/select>');
      document.write('<\/form>');
      document.close();
      
    </script><noscript><p class="toc"><a href="toc.html">Table of Contents</a></p></noscript>
<hr class="hrhead">
<h1 class="title">
<a name="filesystem"></a><small>Chapter 9:</small> Filesystem</h1>
<hr>
<div class="toc">
<h3>Table of Contents</h3>
<ul>
<li><span class="sect1"><a href="filesystem.html#filesystem_general">9.1 General</a></span></li>
<li><span class="sect1"><a href="filesystem.html#filesystem_paths">9.2 Paths</a></span></li>
<li><span class="sect1"><a href="filesystem.html#filesystem_files_and_directories">9.3 Files and Directories</a></span></li>
<li><span class="sect1"><a href="filesystem.html#filesystem_fstream">9.4 File Streams</a></span></li>
<li><span class="sect1"><a href="filesystem.html#filesystem_exercises">9.5 Exercises</a></span></li>
</ul>
</div>
<p class="license"><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top"><img src="img/88x31_cc_logo.gif" alt="" width="88" height="31"></a> This book is licensed under a <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top">Creative Commons License</a>.</p>
<hr>
<h2 class="title">
<a name="filesystem_general"></a>9.1 General</h2>
<div class="sect1"><p>The library <a class="link" href="http://www.boost.org/libs/filesystem/">Boost.Filesystem</a> simplifies working with files and directories. It provides a class named <code class="classname">boost::filesystem::path</code> that allows to process paths. In addition, many functions are available to create directories or to validate a given file for example.</p></div>
<hr>
<h2 class="title">
<a name="filesystem_paths"></a>9.2 Paths</h2>
<div class="sect1">
<p><code class="classname">boost::filesystem::path</code> is the central class in Boost.Filesystem representing path information and providing methods to process them.</p>
<p>In particular, <code class="classname">boost::filesystem::path</code> is actually a <code class="code">typedef</code> for <code class="code">boost::filesystem::basic_path&lt;std::string&gt;</code>. Additionally, <code class="classname">boost::filesystem::wpath</code> is provided as a <code class="code">typedef</code> for <code class="code">boost::filesystem::basic_path&lt;std::wstring&gt;</code>.</p>
<p>All definitions are part of the <span class="package">boost::filesystem</span> namespace which is defined in <code class="filename">boost/filesystem.hpp</code>.</p>
<p>Paths can be built by passing a corresponding string to the <code class="classname">boost::filesystem::path</code> class.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 

int main() 
{ 
  boost::filesystem::path p1("C:\\"); 
  boost::filesystem::path p2("C:\\Windows"); 
  boost::filesystem::path p3("C:\\Program Files"); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.1/main.cpp">Download source code</a></li></ul>
<p>None of the constructors of <code class="classname">boost::filesystem::path</code> actually validates the path provided or checks whether or not the given file or directory exists. Thus, <code class="classname">boost::filesystem::path</code> can be instantiated even with meaningless paths.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 

int main() 
{ 
  boost::filesystem::path p1("..."); 
  boost::filesystem::path p2("\\"); 
  boost::filesystem::path p3("@:"); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.2/main.cpp">Download source code</a></li></ul>
<p>The reason the above program can be executed without any issue is that paths are just strings. <code class="classname">boost::filesystem::path</code> only processes strings; the file system is not being accessed.</p>
<p><code class="classname">boost::filesystem::path</code> certainly provides methods to retrieve a path as a string. Interestingly, there are three different methods available.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Windows\\System"); 
  std::cout &lt;&lt; p.string() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.file_string() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.directory_string() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.3/main.cpp">Download source code</a></li></ul>
<p>The <code class="methodname">string()</code> method returns a so-called portable path. In other words, Boost.Filesystem uses its own predefined rules to normalize the given string. In the above example, <code class="methodname">string()</code> returns <code class="computeroutput">C:/Windows/System</code>. As can be seen, Boost.Filesystem internally uses the slash character <code class="code">/</code> as the separator for file and directory names.</p>
<p>The whole purpose of portable paths is to uniquely identify files and directories across different platforms such as Windows or Linux. The usage of preprocessor macros to encode paths depending on the underlying operating system is therefore no longer needed. The rules for building portable paths mostly comply with the POSIX standard and are outlined in the <a class="link" href="http://www.boost.org/libs/filesystem/doc/reference.html">Boost.Filesystem reference</a>.</p>
<p>Please note that the constructor of <code class="classname">boost::filesystem::path</code> supports both portable and platform dependent paths. The path "C:\\Windows\\System" used in the above example is not portable but rather specific to Windows. It will be recognized correctly by Boost.Filesystem but only if the program is executed on the Windows operating system! When executed on a POSIX compliant operating system such as Linux, <code class="methodname">string()</code> will actually return <code class="computeroutput">C:\Windows\System</code>. Since the backslash character <code class="code">\</code> in Linux is not used as a separator in neither the portable nor the native format, Boost.Filesystem does not recognize it as being a separator for files and directories either.</p>
<p>Many times, it will be inevitable to use platform dependent paths as strings. One example is the usage of operating system functions that expect a platform dependent encoding. The <code class="methodname">file_string()</code> and <code class="methodname">directory_string()</code> methods are offered for exactly this purpose.</p>
<p>Both methods return <code class="computeroutput">C:\Windows\System</code> in the above example - independent of the underlying operating system. While the string is a valid path on Windows, it is neither portable nor platform dependent on a Linux system as explained in the previous section.</p>
<p>The following example uses a portable path to initialize <code class="classname">boost::filesystem::path</code>.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("/"); 
  std::cout &lt;&lt; p.string() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.file_string() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.directory_string() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.4/main.cpp">Download source code</a></li></ul>
<p>Since <code class="methodname">string()</code> returns a portable path, it equals the one used to initialize <code class="classname">boost::filesystem::path</code>: <code class="computeroutput">/</code>. The <code class="methodname">file_string()</code> and <code class="methodname">directory_string()</code> methods, however, return different results based on the underlying platform. In Windows, both return <code class="computeroutput">\</code> while in Linux, both return <code class="computeroutput">/</code> instead.</p>
<p>One might wonder why there are two different methods returning platform dependent paths. Until now, <code class="methodname">file_string()</code> and <code class="methodname">directory_string()</code> always returned the same value in the shown examples. However, there are operating systems that may return different results. Since Boost.Filesystem aims to support as many operating systems as possible, it actually provides two methods to accommodate accordingly. Even though one may be more familiar with Windows or POSIX systems such as Linux, it is recommended to use <code class="methodname">file_string()</code> for retrieving path information for files and <code class="methodname">directory_string()</code> for retrieving path information for directories, respectively. This certainly increases the portability of the code.</p>
<p><code class="classname">boost::filesystem::path</code> provides several methods to access certain components of a path.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Windows\\System"); 
  std::cout &lt;&lt; p.root_name() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.root_directory() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.root_path() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.relative_path() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.parent_path() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.filename() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.5/main.cpp">Download source code</a></li></ul>
<p>If executed on a Windows operating system, the string "C:\\Windows\\System" is interpreted as a platform dependent path information. Consequently, <code class="methodname">root_name()</code> returns <code class="computeroutput">C:</code>, <code class="methodname">root_directory()</code> returns <code class="computeroutput">/</code>, <code class="methodname">root_path()</code> returns <code class="computeroutput">C:/</code>, <code class="methodname">relative_path()</code> returns <code class="computeroutput">Windows/System</code>, <code class="methodname">parent_path()</code> returns <code class="computeroutput">C:/Windows</code>, and <code class="methodname">filename()</code> returns <code class="computeroutput">System</code>.</p>
<p>As seen, no platform dependent path information is returned. None of the returned values contains a backslash <code class="code">\</code> but rather a slash <code class="code">/</code>. If platform dependent information is required, <code class="methodname">file_string()</code> or <code class="methodname">directory_string()</code> should be used instead. In order to use these methods on individual components of a path, a new object of type <code class="classname">boost::filesystem::path</code> must be created and initialized accordingly.</p>
<p>If the above program is executed on a Linux operating system instead, the returned values are different. Most of the methods return an empty character stream except <code class="methodname">relative_path()</code> and <code class="methodname">filename()</code> which return <code class="computeroutput">C:\Windows\System</code> instead. Thus, the string "C:\\Windows\\System" is interpreted as a file name in Linux which is understandable given that it is neither a portable encoding of a path nor a platform depending encoding supported by Linux. Boost.Filesystem therefore has no other choice than interpreting the complete string as a file name.</p>
<p>Boost.Filesystem also provides additional methods to verify whether a specific substring is contained within a path. These methods are: <code class="methodname">has_root_name()</code>, <code class="methodname">has_root_directory()</code>, <code class="methodname">has_root_path()</code>, <code class="methodname">has_relative_path()</code>, <code class="methodname">has_parent_path()</code> and <code class="methodname">has_filename()</code>. Each method returns a value of type <code class="type">bool</code>.</p>
<p>There are two more methods used to split a file name into its components. These should only be applied if <code class="methodname">has_filename()</code> returned <code class="literal">true</code> though. Otherwise, they will simply return empty strings since if there is no file name, there is nothing to split.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("photo.jpg"); 
  std::cout &lt;&lt; p.stem() &lt;&lt; std::endl; 
  std::cout &lt;&lt; p.extension() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.6/main.cpp">Download source code</a></li></ul>
<p>The program returns <code class="computeroutput">photo</code> for <code class="methodname">stem()</code> as well as <code class="computeroutput">.jpg</code> for <code class="methodname">extension()</code>, respectively.</p>
<p>Instead of accessing the components of a path via method calls, one can also iterate over the components itself.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Windows\\System"); 
  for (boost::filesystem::path::iterator it = p.begin(); it != p.end(); ++it) 
    std::cout &lt;&lt; *it &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.7/main.cpp">Download source code</a></li></ul>
<p>If executed on Windows, the program will successively output <code class="computeroutput">C:</code>, <code class="computeroutput">/</code>, <code class="computeroutput">Windows</code> and <code class="computeroutput">System</code>. On a different operating system such as Linux, the output will rather be <code class="computeroutput">C:\Windows\System</code>.</p>
<p>While the previous examples showed various methods to access different components of a path, the following example shows a method to modify path information instead.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\"); 
  p /= "Windows\\System"; 
  std::cout &lt;&lt; p.string() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.2.8/main.cpp">Download source code</a></li></ul>
<p>Using the overloaded <code class="methodname">operator/=()</code> operator, the example appends a path to another one. In Windows, the program will output <code class="computeroutput">C:\Windows\System</code> accordingly. In Linux, the output will rather be <code class="computeroutput">C:\/Windows\System</code> since the slash character <code class="code">/</code> is the separator for files and directories. The slash is also the reason for overloading the <code class="methodname">operator/=()</code> operator: After all, the slash is part of the method name.</p>
<p>Besides the <code class="methodname">operator/=()</code>, Boost.Filesystem offers only the <code class="methodname">remove_filename()</code> and <code class="methodname">replace_extension()</code> methods for modifying path information.</p>
</div>
<hr>
<h2 class="title">
<a name="filesystem_files_and_directories"></a>9.3 Files and Directories</h2>
<div class="sect1">
<p>The methods presented with <code class="classname">boost::filesystem::path</code> internally simply process strings. They allow to access individual components of a path, appending paths to each other and so on.</p>
<p>In order to work with physical files and directories on the hard drive, several independent functions are provided. They expect one or more parameters of type <code class="classname">boost::filesystem::path</code> and call operating system functions for the passed files or directories internally.</p>
<p>Prior to introducing different functions, it is important to understand what happens in the case of an error. All of the functions access operating system functions internally that certainly can fail. In case of a failure, an exception of type <code class="exceptionname">boost::filesystem::filesystem_error</code> will be thrown. This class is derived from <code class="exceptionname">boost::system::system_error</code> and thus fits itself within the Boost.System framework.</p>
<p>Apart from the <code class="methodname">what()</code> and <code class="methodname">code()</code> methods, inherited from the parent class <code class="exceptionname">boost::system::system_error</code>, two additional methods are available: <code class="methodname">path1()</code> and <code class="methodname">path2()</code>. Both return an object of type <code class="classname">boost::filesystem::path</code> so that path information can be determined easily in case of an error - even while working with functions expecting two parameters of type <code class="classname">boost::filesystem::path</code>.</p>
<p>Many functions exist in two variations: One throwing an exception of type <code class="exceptionname">boost::filesystem::filesystem_error</code> while the other returns an object of type <code class="classname">boost::system::error_code</code> in case of a failure. For the latter one, the return value needs to be explicitly inspected to determine a failure.</p>
<p>The following example introduces a function that allows to query the status of a file or directory.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\"); 
  try 
  { 
    boost::filesystem::file_status s = boost::filesystem::status(p); 
    std::cout &lt;&lt; boost::filesystem::is_directory(s) &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.1/main.cpp">Download source code</a></li></ul>
<p><code class="function">boost::filesystem::status()</code> returns an object of type <code class="classname">boost::filesystem::file_status</code> that can be passed to additional helper functions for evaluation. For example, <code class="function">boost::filesystem::is_directory()</code> will return <code class="literal">true</code> if the status for a directory was queried. Besides <code class="function">boost::filesystem::is_directory()</code>, other functions such as <code class="function">boost::filesystem::is_regular_file()</code>, <code class="function">boost::filesystem::is_symlink()</code> and <code class="function">boost::filesystem::exists()</code> are available, all returning a value of type <code class="type">bool</code>.</p>
<p>Apart from <code class="function">boost::filesystem::status()</code>, a second function named <code class="function">boost::filesystem::symlink_status()</code> exists that can be used to query the status of a symbolic link. In this case, the status of the file referred to by the symbolic link is actually queried. In Windows, symbolic links are recognized by the <code class="filename">lnk</code> file extension.</p>
<p>A different category of functions allows to query the attributes instead.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Windows\\win.ini"); 
  try 
  { 
    std::cout &lt;&lt; boost::filesystem::file_size(p) &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.2/main.cpp">Download source code</a></li></ul>
<p>The <code class="function">boost::filesystem::file_size()</code> function returns the size of a file in bytes.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;ctime&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Windows\\win.ini"); 
  try 
  { 
    std::time_t t = boost::filesystem::last_write_time(p); 
    std::cout &lt;&lt; std::ctime(&amp;t) &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.3/main.cpp">Download source code</a></li></ul>
<p>To determine the time a file was modified last, <code class="function">boost::filesystem::last_write_time()</code> is used.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\"); 
  try 
  { 
    boost::filesystem::space_info s = boost::filesystem::space(p); 
    std::cout &lt;&lt; s.capacity &lt;&lt; std::endl; 
    std::cout &lt;&lt; s.free &lt;&lt; std::endl; 
    std::cout &lt;&lt; s.available &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.4/main.cpp">Download source code</a></li></ul>
<p><code class="function">boost::filesystem::space()</code> is used to retrieve the total and remaining disk space. It returns an object of type <code class="classname">boost::filesystem::space_info</code> that defines three public properties: <var>capacity</var>, <var>free</var> and <var>available</var>. All properties are of type <code class="type">boost::uintmax_t</code> which is defined in the Boost.Integer library and is typically a typedef for <code class="code">unsigned long long</code>. The disk space is therefore calculated in bytes.</p>
<p>While all functions presented so far leave files and directories untouched, there exist several functions that allow to create, rename or delete files and directories.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("C:\\Test"); 
  try 
  { 
    if (boost::filesystem::create_directory(p)) 
    { 
      boost::filesystem::rename(p, "C:\\Test2"); 
      boost::filesystem::remove("C:\\Test2"); 
    } 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.5/main.cpp">Download source code</a></li></ul>
<p>The above example should be self-explanatory. By looking closely, it can be seen that not always an object of type <code class="classname">boost::filesystem::path</code> is passed to the individual function but rather a simple string. This is actually possible since <code class="classname">boost::filesystem::path</code> offers a non-explicit constructor which will convert simple strings to objects of type <code class="classname">boost::filesystem::path</code> internally. This actually simplifies the usage of Boost.Filesystem since the creation of explicit objects is not required.</p>
<p>Additional functions such as <code class="function">create_symlink()</code> to create a symbolic link or <code class="function">copy_file()</code> to copy a file or directory are available as well.</p>
<p>The following example presents a function that creates an absolute path based on a file name or section of a path.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  try 
  { 
    std::cout &lt;&lt; boost::filesystem::complete("photo.jpg") &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.6/main.cpp">Download source code</a></li></ul>
<p>Which path is actually displayed depends on the directory the program is executed within. If for example executed from within <code class="filename">C:\</code>, the output will be <code class="computeroutput">C:/photo.jpg</code>.</p>
<p>Please note again the slash character <code class="code">/</code>! If a platform dependent path is desired, an object of type <code class="classname">boost::filesystem::path</code> needs to be initialized and <code class="methodname">file_string()</code> must be called.</p>
<p>To retrieve an absolute path relative to a different directory, a second parameter can be passed to <code class="function">boost::filesystem::complete()</code>.</p>
<pre class="programlisting">#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  try 
  { 
    std::cout &lt;&lt; boost::filesystem::complete("photo.jpg", "D:\\") &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.7/main.cpp">Download source code</a></li></ul>
<p>Now the program displays <code class="computeroutput">D:/photo.jpg</code>.</p>
<p>Finally, a useful helper function to retrieve the current working directory is shown in the following example.</p>
<pre class="programlisting">#include &lt;windows.h&gt; 
#include &lt;boost/filesystem.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  try 
  { 
    std::cout &lt;&lt; boost::filesystem::current_path() &lt;&lt; std::endl; 
    SetCurrentDirectory("C:\\"); 
    std::cout &lt;&lt; boost::filesystem::current_path() &lt;&lt; std::endl; 
  } 
  catch (boost::filesystem::filesystem_error &amp;e) 
  { 
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; 
  } 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.3.8/main.cpp">Download source code</a></li></ul>
<p>The above program can only be executed in Windows due to the <code class="function">SetCurrentDirectory()</code> function. This function modifies the current working directory so that both calls to <code class="function">boost::filesystem::current_path()</code> return different results.</p>
<p>There exists a <code class="function">boost::filesystem::initial_path()</code> function returning the directory from within the application has been started. However, this function depends on additional support from the operating system and thus is not recommended if portability is required. In this case, the return value of <code class="function">boost::filesystem::current_path()</code> should be saved at the beginning of the program for future use as recommended by the documentation for Boost.Filesystem.</p>
</div>
<hr>
<h2 class="title">
<a name="filesystem_fstream"></a>9.4 File Streams</h2>
<div class="sect1">
<p>The C++ standard defines various file streams in the <code class="filename">fstream</code> header. These streams certainly do not accept a parameter of type <code class="classname">boost::filesystem::path</code>. Since the Boost.Filesystem library will most likely be included in the Technical Report 2 of the C++ standard, the file streams will be extended by corresponding constructors though. In order to currently work with file streams and path information of type <code class="classname">boost::filesystem::path</code>, the header <code class="filename">boost/filesystem/fstream.hpp</code> can be accessed. It provides the required additions to file streams that will be added to the C++ standard in the future based on the Technical Report 2.</p>
<pre class="programlisting">#include &lt;boost/filesystem/fstream.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::filesystem::path p("test.txt"); 
  boost::filesystem::ofstream ofs(p); 
  ofs &lt;&lt; "Hello, world!" &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/9.4.1/main.cpp">Download source code</a></li></ul>
<p>Not only the constructors but also the overloaded <code class="methodname">open()</code> methods accept parameters of type <code class="classname">boost::filesystem::path</code>.</p>
</div>
<hr>
<h2 class="title">
<a name="filesystem_exercises"></a>9.5 Exercises</h2>
<div class="sect1">
<p class="solution">
              You can buy 
              <a target="_top" href="http://en.highscore.de/shop/index.php?p=boost-solution">solutions to all exercises</a>
              in this book as a ZIP file. 
            </p>
<ol><li class="listitem"><p>Create a program that creates an absolute path for a file named <code class="computeroutput">data.txt</code> that resides in a directory one level above the current working directory of the application. For example, if the program is executed from within <code class="computeroutput">C:\Program Files\Test</code>, it should display <code class="computeroutput">C:\Program Files\data.txt</code> accordingly.</p></li></ol>
</div>
</div>
<hr class="hrfoot">
<p class="copyright">Copyright © 2008-2010 
        <a class="link" href="mailto:boris@highscore.de">Boris Schäling</a>
      </p>
</body>
</html>
